/* Copyright (c) 2022-2025 Qualcomm Technologies International, Ltd. */
/* %%version */

#ifndef GATT_XPAN_CLIENT_PRIVATE_H_
#define GATT_XPAN_CLIENT_PRIVATE_H_

#include "csr_synergy.h"

#ifndef EXCLUDE_GATT_XPAN_CLIENT_MODULE

#include "csr_list.h"
#include "service_handle.h"
#include "csr_bt_gatt_client_util_lib.h"
#include "csr_bt_uuids.h"
#include "gatt_xpan_client.h"

/* Handles of the XPAN characteristics. */
typedef struct
{
    uint16 startHandle;
    uint16 endHandle;
} gatt_xpan_client_data_t;

/*
    @brief Client library private data.
*/
typedef struct __GXPANC
{
    AppTask app_task;

    /* This is used to store the handle of the characteristic when a descriptor discovery is pending */
    uint16 pending_handle;

    /* Any read/write command pending */
    uint16 pending_cmd;

    /* This is used to count all the received reading confirmations during the initialization */
    CsrBtUuid128 nextDescriptorHandle;

    /* XPAN Handles */
    GattXpanClientDeviceData handles;

    gatt_xpan_client_data_t clientData;

    /*client Data is set or not*/
    bool clientDataIsSet;

    ServiceHandleListElm_t *srvcElem;
} GXPANC;

typedef struct gatt_xpan_client
{
    AppTaskData lib_task;
    CsrCmnList_t serviceHandleList;
} gatt_xpan_client;


typedef struct
{
    connection_id_t cid;
    uint16 start_handle;
    uint16 end_handle;
} gatt_xpan_client_registration_params_t;

/* Macros for creating messages */
#define MAKE_XPAN_CLIENT_MESSAGE(TYPE) TYPE *message = (TYPE *) CsrPmemZalloc(sizeof(TYPE));
#define MAKE_XPAN_CLIENT_INTERNAL_MESSAGE(TYPE) TYPE##_T *message = (TYPE##_T *) CsrPmemZalloc(sizeof(TYPE##_T));
#define MAKE_XPAN_CLIENT_MESSAGE_WITH_LEN(TYPE, LEN) TYPE *message = (TYPE *) CsrPmemZalloc(sizeof(TYPE) + (LEN))
#define MAKE_XPAN_CLIENT_INTERNAL_MESSAGE_WITH_LEN(TYPE, LEN) TYPE##_T *message = (TYPE##_T *) calloc(1,sizeof(TYPE##_T) + (LEN))

/* Type LIB internal messages */
typedef int32 XpanClientInternalMsgType;

#define XPAN_CLIENT_INTERNAL_MSG_NOTIFICATION_REQ                             ((XpanClientInternalMsgType) 0x01)
#define XPAN_CLIENT_INTERNAL_MSG_READ_CCC                                     ((XpanClientInternalMsgType) 0x02)
#define XPAN_CLIENT_INTERNAL_MSG_READ                                         ((XpanClientInternalMsgType) 0x03)
#define XPAN_CLIENT_INTERNAL_MSG_INIT_READ                                    ((XpanClientInternalMsgType) 0x04)
#define XPAN_CLIENT_INTERNAL_MSG_WRITE                                        ((XpanClientInternalMsgType) 0x05)
#define XPAN_CLIENT_INTERNAL_MSG_NOTIFY_READ                                  ((XpanClientInternalMsgType) 0x06)
#define XPAN_CLIENT_INTERNAL_MSG_TOP                                          ((XpanClientInternalMsgType) 0x07)

#define XPAN_CLIENT_INTERNAL_MSG_WRITE_CONNECT_SSID_OPCODE_REQ                ((XpanClientInternalMsgType) 0x08)
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_DISCONNECT_SSID_OPCODE_REQ             ((XpanClientInternalMsgType) 0x09)
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_CONNECTED_SSID_OPCODE_REQ              ((XpanClientInternalMsgType) 0x0A)
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_AVAILABLE_SSID_OPCODE_REQ              ((XpanClientInternalMsgType) 0x0B) /* Available WiFi network that the server could connect to.                                                                                    */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_RELATED_SSIDS_OPCODE_REQ               ((XpanClientInternalMsgType) 0x0C) /* Indicate which WiFi networks are related to each other (i.e. on the same network).                                                          */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_MDNS_SRV_UUID_OPCODE_REQ               ((XpanClientInternalMsgType) 0x0D) /* mDNS SRV UUID that can be used by the server to reconnect to this device using an XPAN bearer.                                              */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_REMOVE_SSID_OPCODE_REQ                 ((XpanClientInternalMsgType) 0x0E) /* WiFi network that the server should no longer connect to.                                                                                   */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_L2CAP_TCP_PORT_OPCODE_REQ              ((XpanClientInternalMsgType) 0x0F) /* TCP port number that can be used to connect to the L2CAP over IP protocol. This shall be connectable using the exposed IP address.          */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_UDP_PORT_OPCODE_REQ                    ((XpanClientInternalMsgType) 0x10) /* UDP port number that can be used to connect to send audio packets to the client. This shall be connectable using the exposed IP address.    */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_ETHER_TYPE_OPCODE_REQ                  ((XpanClientInternalMsgType) 0x11) /* EtherType used for sending audio over Ether packets.                                                                                        */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_MAC_ADDRESS_OPCODE_REQ                 ((XpanClientInternalMsgType) 0x12) /* MAC address of the client.                                                                                                                  */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_BEARER_PREFERENCE_RESPONSE_OPCODE_REQ  ((XpanClientInternalMsgType) 0x13) /* Response to the server's bearer preference.                                                                                                 */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_UPDATE_BEACON_PARAMETERS_OPCODE_REQ    ((XpanClientInternalMsgType) 0x14) /* Update the SAP beacon parameters.                                                                                                           */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_SAP_POWER_STATE_RESPONSE_OPCODE_REQ    ((XpanClientInternalMsgType) 0x15) /* Response to the server's SAP power state request.                                                                                           */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_CLIENT_FEATURES_OPCODE_REQ             ((XpanClientInternalMsgType) 0x16) /* Client's supported features.                                                                                                                */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_AUDIO_BEARER_SWITCH_REQUEST_OPCODE_REQ ((XpanClientInternalMsgType) 0x17) /* Audio bearer switch request.                                                                                                                */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_TWT_CONFIGURATION_REQ                  ((XpanClientInternalMsgType) 0x18) /* TWT Configuration request.                                                                                                                  */
#define XPAN_CLIENT_INTERNAL_MSG_TERMINATE_TWT_SESSION_REQ                    ((XpanClientInternalMsgType) 0x19) /* Terminate TWT session request.                                                                                                              */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_WIFI_SCAN_RESULTS_OPCODE_REQ           ((XpanClientInternalMsgType) 0x1A) /* WiFi Scan Results.                                                                                                                          */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_CHANNEL_SWITCH_ANNOUNCEMENT_OPCODE_REQ ((XpanClientInternalMsgType) 0x1B) /* Channel Switch Announcements.                                                                                                               */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_UDP_SYNC_PORT_OPCODE_REQ               ((XpanClientInternalMsgType) 0x1C) /* UDP Sync Port.                                                                                                                              */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_ROAMING_REQUEST_OPCODE_REQ             ((XpanClientInternalMsgType) 0x1D) /* Roaming Request.                                                                                                                            */
#define XPAN_CLIENT_INTERNAL_MSG_WRITE_MULTICAST_MAC_ADDRESS_OPCODE_REQ       ((XpanClientInternalMsgType) 0x1E) /* Multicast MAC Address.                                                                                                                      */ 

/* Internal Message Structure to read the characteristics during the initialization */
typedef struct
{
    XpanClientInternalMsgType id; /*! service message id */
    ServiceHandle serviceHandle;
    uint16 handle;
} XPAN_CLIENT_INTERNAL_MSG_INIT_READ_T;

/* Internal Message Structure to read a client configuration characteristic */
typedef  XPAN_CLIENT_INTERNAL_MSG_INIT_READ_T XPAN_CLIENT_INTERNAL_MSG_READ_CCC_T;

/* Internal Message Structure to read a characteristic */
typedef XPAN_CLIENT_INTERNAL_MSG_INIT_READ_T XPAN_CLIENT_INTERNAL_MSG_READ_T;

typedef XPAN_CLIENT_INTERNAL_MSG_INIT_READ_T XPAN_CLIENT_INTERNAL_MSG_NOTIFY_READ_T;

/* Enumerations for XPAN client message which is pending and yet to process completely  */
typedef enum
{
    xpan_client_pending_none = 0,
    xpan_client_some_xpan_operation_pending
} xpan_client_pending_op_type_t;

/* Opcodes of the XPAN Control Point operations */
typedef enum _xpan_client_control_point_opcodes
{
    xpan_client_some_xpan_operation_op,
    xpan_client_last_op
} xpan_client_control_point_opcodes_t;

/* Assumes message struct with
 *    uint16 size_value;
 *    uint16 value[1];
 */
#define MAKE_XPAN_CLIENT_MESSAGE_WITH_LEN_U16(TYPE, LEN)  \
        TYPE *message = (TYPE*)calloc(1,  \
                        sizeof(TYPE) + \
                        sizeof(uint16) * ((LEN) ? (LEN - 1) : 0))

#define XpanClientMessageSend(TASK, ID, MSG) {\
    MSG->id = ID;\
    CsrSchedMessagePut(TASK, XPAN_CLIENT_PRIM, MSG);\
    }

/*
#define XpanMessageSendConditionally(TASK, ID, MSG, CMD) XpanMessageSend(TASK, ID, MSG)
*/

#define XpanClientMessageSendConditionally(TASK, ID, MSG, CMD) XpanClientMessageSend(TASK, ID, MSG)

#define XPAN_CLIENT_GATT_MTU               64

/* Size of the Client Characteristic Configuration in number of octects */
#define XPAN_CLIENT_CHARACTERISTIC_CONFIG_SIZE          (2)

typedef uint8 XpanClientCharType;
#define XPAN_CLIENT_CHAR_TYPE_CHARACTERISTIC                  ((XpanClientCharType) 0x00)
#define XPAN_CLIENT_CHAR_TYPE_CHARACTERISTIC_CLIENT_CONFIG    ((XpanClientCharType) 0x01)

/*Macro to check 128 UUID*/
/*#define CHECK_UUID(uuid, char_cfm) ((char_cfm->uuid[3] == (uuid[3])) && \
    (char_cfm->uuid[2] == (uuid)) && \
    (char_cfm->uuid[1] == (uint32)(uuid >> 64)) && \
    (char_cfm->uuid[0] == (uint32)(uuid >> 96)))*/

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle srvcHndl;
    uint16 handle;               /* Handle of the CCC to set */
    bool notificationsEnable;    /* Enable or Disable notification */
} XpanClientInternalMsgSetNotification;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientConnectSsidOp connectSsidOp;      /* The Connect SSID Operation structure that is used to write this opcode and in opcode notifications */
} XpanClientInternalMsgConnectSsidReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientDisconnectSsidOp disconnectSsidOp;
} XpanClientInternalMsgDisconnectSsidReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientConnectedSsidOp connectedSsidOp;
} XpanClientInternalMsgConnectedSsidReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientAvailableSsidOp availableSsidOp;
} XpanClientInternalMsgAvailableSsidReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientRelatedSsidsOp relatedSsidsOp;
} XpanClientInternalMsgRelatedSsidsReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientMdnsSrvUuidOp mdnsSrvUuidOp;
} XpanClientInternalMsgMdnsSrvUuidReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientRemoveSsidOp removeSsidOp;
} XpanClientInternalMsgRemoveSsidReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientL2capTcpPortOp l2capTcpPortOp;
} XpanClientInternalMsgL2capTcpPortReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientUdpPortOp udpPortOp;
} XpanClientInternalMsgUdpPortReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientEtherTypeOp etherTypeOp;
} XpanClientInternalMsgEtherTypeReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientMacAddressOp macAddressOp;
} XpanClientInternalMsgMacAddressReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientBearerPreferenceResponseOp bearerPreferenceResponseOp;
} XpanClientInternalMsgBearerPreferenceResponseReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;
    GattXpanClientUpdateBeaconParametersOp updateBeaconParametersOp;
} XpanClientInternalMsgUpdateBeaconParametersReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientSapPowerStateResponseOp sapPowerStateResponseOp;
} XpanClientInternalMsgSapPowerStateResponseReq;

typedef  struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientClientFeaturesOp clientFeaturesOp;
} XpanClientInternalMsgClientFeaturesReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientAudioBearerSwitchRequestOp audioBearerSwitchRequestOp;
} XpanClientInternalMsgAudioBearerSwitchRequestReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    uint8                   scanTimestamp[XPAN_CLIENT_TSF_TIMESTAMP_LENGTH];
    uint8                   numBssids;    /*! This corresponds to the number of ApScanResults */
    XpanClientApScanResult* apScanResult[1];
} XpanClientInternalMsgWiFiScanResultsReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientChannelSwitchAnnouncementOp channelSwitchAnnouncementOp;
} XpanClientInternalMsgChannelSwitchAnnouncementReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientUdpSyncPortOp udpSyncPortOp;
} XpanClientInternalMsgUdpSyncPortReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;
} XpanClientInternalMsgRoamingRequestReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;

    GattXpanClientMulticastMacAddressOp multicastMacAddresOp;
} XpanClientInternalMsgMulticastMacAddressReq;

typedef struct
{
    XpanClientInternalMsgType id;
    ServiceHandle clntHndl;
    GattXpanClientTwtConfiguration  twtConfiguration;
} XpanClientInternalMsgTwtConfigurationReq;

bool xpanClientGetHandle(GXPANC *const gattXpanClient, XpanClientCharacteristicId charId, uint16* handle, XpanClientCharType readType);

void xpanFreeContainedPointersWiFiScanResultsReq(XpanClientInternalMsgWiFiScanResultsReq* msg);
void xpanFreeContainedPointersWiFiScanResultsOp(GattXpanClientWiFiScanResultsOp* op);

#endif /* EXCLUDE_GATT_XPAN_CLIENT_MODULE */
#endif /* GATT_XPAN_CLIENT_PRIVATE_H_ */
